 #include"threadpool.h"
 #include"task.h"
 #include"thread.h"
 #include"result.h"
 #include<functional>
 #include<thread>
 #include<chrono>
 #include<iostream>
 const int TASK_MAX_THREADHOLE = 1024;
 const int THREAD_MAX_THREADHOLE = 10;
 const int THREAD_MAX_IDLE_TIME = 5;//线程最大空闲时间（S）
  ThreadPool::ThreadPool():
  inintSizeOfPool_(0),
  threadSizeThresHold_(THREAD_MAX_THREADHOLE),
  curThreadSize_(0),
  idleThreadSize_(0),
  taskSize_(0),
  taskQueMaxThreshHold_(TASK_MAX_THREADHOLE),
  poolMode_(POOLMODE::MODE_FIXED),
  isPoolRunning_(false)
  {

  } 
  ThreadPool::~ThreadPool()
  {
    isPoolRunning_ =false;
  }
  void ThreadPool::Start(size_t inintSizeOfPool)
  {
    if(inintSizeOfPool > THREAD_MAX_THREADHOLE)
    {
      std::cout<<"输入线程数过多"<<std::endl;
      return ;
    }
     inintSizeOfPool_ = inintSizeOfPool;
     isPoolRunning_ = true;
     for(size_t i =0;i<inintSizeOfPool;++i)
     {
        std::unique_ptr<Thread> ptr(new Thread(std::bind(&ThreadPool::ThreadFunc,this,std::placeholders::_1)));//线程是线程池的，执行的应该是线程池的func
        ptr->Start();
        threadPools_.emplace(ptr->GetThreadId(), std::move(ptr));
     }
      isPoolRunning_ = true;
      std::cout<<"线程池启动"<<std::endl;
      curThreadSize_ = inintSizeOfPool;
      idleThreadSize_ = inintSizeOfPool;
      std::cout<<"初始线程全部启动"<<std::endl;
      
  }
 void ThreadPool::ThreadFunc(int threadId)
 {
    if(isPoolRunning_ == false)
    {
      return ;
    }
    auto lastTime = std::chrono::high_resolution_clock().now();
   while(1)
   {
      std::cout<<std::this_thread::get_id()<<"线程尝试获取任务"<<std::endl;
      std::shared_ptr<Task> task;
      {
        std::unique_lock<std::mutex> lock(taskQueMutx_);
        if(poolMode_ == POOLMODE::MODE_CACHEd)  //如果是cached模式，而且额外创建的线程超过60s空闲，则需要回收它
        {
           while(0 == taskSize_)
           {
               if(std::cv_status::timeout == notEmpty_.wait_for(lock,std::chrono::seconds(1)))//看是否是超时返回
               {
                  auto  now = std::chrono::high_resolution_clock().now();
                  auto  dur = std::chrono::duration_cast<std::chrono::seconds>(now - lastTime);//计算是否过了60S
                  if(dur.count() >= THREAD_MAX_IDLE_TIME && curThreadSize_ > inintSizeOfPool_)
                  {
                     threadPools_.erase(threadId);
                     curThreadSize_--;
                     idleThreadSize_--;
                     std::cout<<std::this_thread::get_id()<<" exit!"<<std::endl;
                     return ;

                  }
               }
           }

        }else
        {
            while(0 == taskSize_)
           {
              notEmpty_.wait(lock);
           }
        }
       
       idleThreadSize_ --;
       task = taskQues_.front();
       taskQues_.pop();
       taskSize_--;
       std::cout<<std::this_thread::get_id()<<"线程获取任务成功"<<std::endl;
       if(taskSize_ > 0)
       {
         notEmpty_.notify_all(); //此时如果还有任务，则通知其它线程也来执行
       }
       notFull_.notify_all();
      }
       //把任务获取之后，就应该把锁释放掉，而不是要等待执行任务结束
      if(nullptr != task)
      { 
         task->exec();
      }
      idleThreadSize_++;
      std::cout<<std::this_thread::get_id()<<"线程任务执行成功"<<std::endl;
      
   }

 }
  void ThreadPool::SetMode(POOLMODE mode)
  {
     if(!isPoolRunning_)
     {
       poolMode_ = mode;
     }
  } 
      
  void ThreadPool::SetTaskMaxThreshHold(size_t threshHold)
  {
   if(!isPoolRunning_)
   {
      taskQueMaxThreshHold_ = threshHold;
   }
        
  } 
void ThreadPool:: SetThreadMaxThreshHold(size_t threshHold)
{
  if(isPoolRunning_)
  {
    return ;
  }
  if(poolMode_ == POOLMODE::MODE_CACHEd)
  {
   threadSizeThresHold_ = threshHold;
  }
}
 Result ThreadPool::SubmitTask(std::shared_ptr<Task> sp)
  {
    
     std::unique_lock<std::mutex> lock(taskQueMutx_);
     if(!notFull_.wait_for(lock,std::chrono::seconds(1),[&]()->bool{return taskSize_ < taskQueMaxThreshHold_;}))//如果等待1秒，还没成功，则返回失败（降级服务）
     {
        std::cerr<<"任务队列已满，提交失败"<<std::endl;
         return Result(sp,false);
     }
     
     taskQues_.emplace(sp);
     taskSize_++;
     notEmpty_.notify_all();

     if(poolMode_ == POOLMODE::MODE_CACHEd && taskSize_ > idleThreadSize_ && curThreadSize_ < threadSizeThresHold_) //Cached 处理小而快的任务，因为如果要处理这个任务的时间比较长的话，那么会导致一直创建线程
     {
        std::cout<<"任务过多，需要再产生线程"<<std::endl;
        std::unique_ptr<Thread> ptr(new Thread(std::bind(&ThreadPool::ThreadFunc,this,std::placeholders::_1)));
        ptr->Start();
        threadPools_.emplace(ptr->GetThreadId(), std::move(ptr));
        curThreadSize_++;
        idleThreadSize_++;
        std::cout<<"create new thread!"<<std::this_thread::get_id()<<std::endl;
     }

     //return task->getResult();  //用task的方法返回Result  task执行完之后，task对象没有了，所以不能
     return Result(sp);  //用tash生成Result来返回
  } 
 

//int main()
//{
//    ThreadPool pool;
//    pool.Start();
//   std::this_thread::sleep_for(std::chrono::seconds(2));
//   return 0;
//}